<template>
  <!-- 这个组件不需要渲染任何可见内容，它是一个纯服务组件 -->
  <div style="display: none;"></div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue'

// WebSocket 连接实例
const socket = ref<WebSocket | null>(null)
// 音频上下文，用于处理和播放音频流
const audioContext = ref<AudioContext | null>(null)
// 音频源节点
const audioSource = ref<MediaStreamAudioSourceNode | null>(null)
// 音频队列，用于存储待处理的音频数据
const audioQueue = ref<ArrayBuffer[]>([])
// 音频处理状态标志
const isProcessingAudio = ref(false)

// 初始化 WebSocket 连接
const initWebSocket = () => {
  try {
    // 这里使用一个占位的连接地址，实际项目中需要替换为真实的 WebSocket 端点
    // 1到100 随机值
    const wsUrl = 'ws://192.168.124.41:8000/ai/chat?clientId='+ (Math.floor(Math.random() * 100) + 1).toString() // 示例地址
    socket.value = new WebSocket(wsUrl)

    // 连接建立时的处理函数
    socket.value.onopen = () => {
      console.log('WebSocket 音频流连接已建立')
      // 连接建立后不需要发送任何初始化信息，后端会负责音频发送时机
    }

    // 接收消息的处理函数 - 只处理音频数据
    socket.value.onmessage = (event) => {
      if (event.data instanceof ArrayBuffer) {
        handleAudioData(event.data)
      }
    }

    // 连接关闭时的处理函数
    socket.value.onclose = (event) => {
      console.log('WebSocket 音频流连接已关闭', event)
      // 实现自动重连机制
      if (!event.wasClean) {
        console.log('音频流连接意外关闭，将在3秒后尝试重连...')
        setTimeout(initWebSocket, 3000)
      }
    }

    // 连接错误时的处理函数
    socket.value.onerror = (error) => {
      console.error('WebSocket 音频流连接错误:', error)
    }
  } catch (error) {
    console.error('初始化 WebSocket 音频流连接失败:', error)
  }
}

// 初始化音频上下文
const initAudioContext = () => {
  if (audioContext.value) return
  
  try {
    // 创建音频上下文
    audioContext.value = new (window.AudioContext || (window as any).webkitAudioContext)()
    console.log('音频上下文已初始化')
  } catch (error) {
    console.error('初始化音频上下文失败:', error)
  }
}

// 处理接收到的音频数据
const handleAudioData = (data: ArrayBuffer) => {
  // 确保音频上下文已初始化
  if (!audioContext.value) {
    initAudioContext()
  }

  // 将接收到的音频数据加入队列
  audioQueue.value.push(data)
  
  // 如果当前没有在处理音频，则开始处理队列
  if (!isProcessingAudio.value) {
    processAudioQueue()
  }
}

// 处理音频队列并播放
const processAudioQueue = async () => {
  if (!audioContext.value || audioQueue.value.length === 0) {
    isProcessingAudio.value = false
    return
  }

  isProcessingAudio.value = true

  try {
    // 获取队列中的第一个音频数据
    const audioData = audioQueue.value.shift()
    if (!audioData) {
      isProcessingAudio.value = false
      return
    }

    // 处理音频数据并播放
    await decodeAndPlayAudio(audioData)
    
    // 继续处理队列中的下一个音频数据
    processAudioQueue()
  } catch (error) {
    console.error('处理音频队列失败:', error)
    isProcessingAudio.value = false
  }
}

// 解码并播放音频数据
const decodeAndPlayAudio = async (audioData: ArrayBuffer): Promise<void> => {
  if (!audioContext.value) {
    return
  }

  try {
    // 解码音频数据
    const audioBuffer = await audioContext.value.decodeAudioData(audioData)
    
    // 创建音频源节点
    const source = audioContext.value.createBufferSource()
    source.buffer = audioBuffer
    
    // 连接到音频输出设备
    source.connect(audioContext.value.destination)
    
    // 播放音频
    source.start()
    
    console.log('正在播放音频片段，时长:', audioBuffer.duration, '秒')
    
    // 等待音频播放完成
    return new Promise(resolve => {
      source.onended = () => {
        resolve()
      }
    })
  } catch (error) {
    console.error('解码或播放音频失败:', error)
    throw error
  }
}

// 组件挂载时自动初始化连接
onMounted(() => {
  console.log('WebSocketService 组件已挂载，自动启动音频流接收服务...')
  initWebSocket()
})

// 组件卸载时关闭连接和清理资源
onUnmounted(() => {
  console.log('WebSocketService 组件将卸载，清理音频流接收服务...')
  
  // 关闭 WebSocket 连接
  if (socket.value) {
    socket.value.close(1000, '组件卸载')
    socket.value = null
  }
  
  // 关闭音频上下文
  if (audioContext.value) {
    audioContext.value.close()
    audioContext.value = null
  }
  
  // 清空音频队列
  audioQueue.value = []
  isProcessingAudio.value = false
})

// 不需要暴露任何方法，组件完全自包含
</script>

<style scoped>
/* 这个组件不需要样式 */
</style>